var $ = window.$;
var sample = require('../../sample/manager');
var frac = require('../../../util/frac');
var layer = require('../../layer/manager');
var sound = require('../../audio/sound');
var timing = require('../../timing/manager');
var timeline = require('../../timeline/ui');
var config = require('../../../core/config');
var notify = require('../../notify/ui');

/**
 * 非独立模块, 作为ui的插件
 */

var ret = {
    Intent_Add_Hold_Start: 1,
    Intent_Add_Normal: 1 << 1,
    Intent_Add_Hold_End: 1 << 2,
    Intent_Drag: 1 << 3,
    Intent_Select: 1 << 4,
    Intent_Cancel_Select: 1 << 5,
    Intent_Del_Current: 1 << 6,
    editData: {
        currBlockIndex: null,
        currHoldNote: null,
        isSelectedBeforeClick: false,
        currNote: null,
        startMousePos: null,
        isCtrlBeforeMouseUp: false,
        deltaMovingIndex: 0,
        startMovingIndex: 0,
        movingNotes: null
    },
    intent: null,

    setUI: function (_ui) {
        this.ui = _ui;
    },

    onPadMouseDown: function (e) {
        var triggerKey = e.which;
        var data = this.editData;

        if (this.intent == this.Intent_Add_Hold_End) {
            return;
        }
        if (data.currBlockIndex == -1 && this.intent != this.Intent_Add_Hold_End) {
            this.intent = this.Intent_Cancel_Select;
            return;
        }
        var note = this.ui.playingNote[data.currBlockIndex];
        data.currNote = note;
        data.startMousePos = [e.pageX, e.pageY];
        data.isCtrlBeforeMouseUp = e.ctrlKey;
        if (!note && !e.shiftKey) {
            this.intent = this.Intent_Add_Normal;
        } else if (!note && e.shiftKey) {
            this.intent = this.Intent_Add_Hold_Start;
        } else if (note && triggerKey == 3) {
            this.intent = this.Intent_Del_Current;
        } else if (note && triggerKey != 3) {
            this.intent = this.Intent_Select;
        }
    },

    onPadMouseUp: function (e) {
        var currTime = sound.stableTime();
        var ui = this.ui;
        var beat = timing.timeToBeat(currTime, ui.divide);
        var data = this.editData;
        var index = data.currBlockIndex;
        if (this.intent == this.Intent_Add_Normal && index !== undefined) {
            if (this.ui.getSelectIds().length) {
                this.ui.cancelSelect();
            } else {
                var note = {
                    index: index,
                    beat: beat,
                    time: timing.beatToTime(beat)
                };
                this.ui.addTouchNote(note);
                this.ui.reInitSeekQueue();
            }
        } else if (this.intent == this.Intent_Del_Current) {
            this.removePadNote(data.currNote);
            this.ui.reInitSeekQueue();
        } else if (this.intent == this.Intent_Select) {
            this.selectPadNote(e, data.currNote);
            this.intent = null;
        } else if (this.intent == this.Intent_Cancel_Select) {
            this.selectPadNote(e, null);
        } else if (this.intent == this.Intent_Add_Hold_Start) {
            this.drawHoldNoteStartPoint(index);
            this.intent = this.Intent_Add_Hold_End;
        } else if (this.intent == this.Intent_Add_Hold_End) {
            this.drawHoldNoteEndPoint();
            this.ui.reInitSeekQueue();
        } else if (this.intent == this.Intent_Drag) {
            this.intent = null;
        }
    },

    onPadMouseMove: function (e) {
        var currIndex = this.ui.mousePosToBlockIndex(e);
        var data = this.editData;
        data.currBlockIndex = currIndex;
        var startPos = data.startMousePos;
        if (this.intent == this.Intent_Select) {
            if (Math.abs(startPos[0] - e.pageX) > 10 || Math.abs(startPos[1] - e.pageY) > 10) {
                this.intent = this.Intent_Drag;
                data.movingNotes = [];
                if (this.ui.selectedNotes[data.currNote.id]) {
                    data.movingNotes = this.ui.getSelectedNotesInScreen();
                } else {
                    data.movingNotes = [data.currNote];
                }
                data.startMovingIndex = data.currBlockIndex;
            }
        }
        else if (this.intent == this.Intent_Drag) {
            if (currIndex >= 0) {
                this.tryMoveNotes(currIndex);
                this.ui.drawNotes();
            }
        }
    },

    tryMoveNotes: function (currIndex) {
        var data = this.editData;
        if (currIndex == data.startMovingIndex) {
            return;
        }
        var notes = data.movingNotes;
        for (var i = 0; i < notes.length; i++) {
            var note = notes[i];
            if (!this.simulateMoveNoteTo(note, currIndex)) {
                return;
            }
        }
        for (var i = 0; i < notes.length; i++) {
            var note = notes[i];
            this.ui.cavRemoveNote(note.index);
            this.moveSingleNote(note, note.index + data.deltaMovingIndex);
        }
        data.startMovingIndex = currIndex;
        //this.ui.reInitSeekQueue();
    },


    moveSingleNote: function (note, toIndex) {
        var grid = this.ui.playingNote;
        var index = note.index;
        grid[index] = null;
        grid[toIndex] = note;
        note.index = toIndex;
    },

    /**
     * 将note移动到某位置
     * @param note 当前被选中的对象
     * @param newIndex 鼠标位置的方块编号
     * @returns {boolean} simulate=true时返回true表示这次移动可以进行
     */
    simulateMoveNoteTo: function (note, newIndex) {
        var idx = note.index;
        var grid = this.ui.playingNote;
        var data = this.editData;
        //使用鼠标对着的方块计算行列位移
        var rc = this.ui.rowCount;
        var oldRow = Math.floor(data.startMovingIndex / rc);
        var oldCol = data.startMovingIndex % rc;
        var newRow = Math.floor(newIndex / rc);
        var newCol = newIndex % rc;
        data.deltaMovingIndex = newIndex - data.startMovingIndex;
        //这里要把index差值变成xy的行列差值 为了保证原来在一行的方块不至于移动变两行
        var toRow = Math.floor(idx / rc) + (newRow - oldRow);
        var toCol = idx % rc + (newCol - oldCol);
        if (!(toRow >= 0 && toRow < rc && toCol >= 0 && toCol < rc)) {
            return false;
        }
        var newIdx = note.index + data.deltaMovingIndex;
        //如果目标位置有touch点会阻止移动 但是目标的touch点也处于选中状态就无所谓了
        var target = grid[newIdx];
        if (target) {
            var isTargetSelected = this.ui.selectedNotes[target.id];
            if (isTargetSelected) {
                // 但是复制不行
                if (data.isCtrlBeforeMouseUp) {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    },

    removePadNote: function (note) {
        var idx = note.index;
        var grid = this.ui.playingNote;
        this.ui.cavRemoveNote(note.index);
        this.ui.manager.removeNote(note.id);
        delete this.ui.selectedNotes[note.id];
        grid[idx] = null;
        this.ui.changeMusicbar(note.beat, -1);
    },

    selectPadNote: function (e, note) {
        if (!note) {
            this.ui.cancelSelect();
            this.ui.clearEditCanvas();
            return;
        }
        if (e.ctrlKey) {
            if (this.ui.selectedNotes[note.id]) {
                delete this.ui.selectedNotes[note.id];
            } else {
                this.ui.selectedNotes[note.id] = true;
            }
        } else {
            this.ui.cancelSelect();
            this.ui.selectedNotes[note.id] = true;
        }

        this.ui.clearEditCanvas();
        this.ui.updateSelectStatus();
        this.ui.pluginMeta.update();
        //if(config.getVal(config.ITEM.PLAYSOUND)){
        //	this.ui.playNote(this.data.note);
        //}
    },

    drawHoldNoteStartPoint: function (index) {
        var ui = this.ui;
        var block = ui.getBlockByIndex(index);
        $("#hold_hint").html(config.i18n("ubt01")).show();
        var beat = timing.timeToBeat(sound.stableTime());
        this.editData.currHoldNote = {
            beat: beat,
            index: index,
            time: sound.stableTime(),
            isDrawing: true
        };
        this.ui.addTouchNoteDiv(this.editData.currHoldNote);
    },

    drawHoldNoteEndPoint: function () {
        var data = this.editData;
        var note = data.currHoldNote;
        if (data.currBlockIndex == -1 || data.currBlockIndex == note.index) {
            notify.addNotify({msg: config.i18n("ubt08")});
            return;
        }
        var rc = this.ui.rowCount;
        var startRow = Math.floor(note.index / rc);
        var endRow = Math.floor(data.currBlockIndex / rc);
        var startCol = note.index % rc;
        var endCol = data.currBlockIndex % rc;
        if (startRow != endRow && startCol != endCol) {
            notify.addNotify({msg: config.i18n("ubt08")});
            return;
        }
        note.endtime = sound.stableTime();
        if (note.endtime <= note.time) {
            notify.addNotify({msg: config.i18n("ubt02")});
            return;
        }
        delete note.isDrawing;
        note.endbeat = timing.timeToBeat(note.endtime, this.ui.divide);
        note.endindex = data.currBlockIndex;
        this.cancelHoldDrawing();
        this.ui.addTouchNote(note, true);
        timeline.seekTo(note.time);
    },

    cancelHoldDrawing: function () {
        if (!this.editData.currHoldNote) {
            return;
        }
        this.ui.cavRemoveNote(this.editData.currHoldNote.index);
        this.editData.currHoldNote = null;
        this.intent = null;
        $("#hold_hint").hide();
        $("#hold_tip_start").hide();
        $("#hold_tip_end").hide();
    }
};

module.exports = ret;